<?php

namespace Upfor\UpforPHP\View;

use ErrorException;
use Upfor\UpforPHP\Interfaces\ViewInterface;

/**
 * Default view
 */
class DefaultView implements ViewInterface {

    /**
     * View data
     *
     * @var array
     */
    protected $data = array();

    /**
     * Settings of view engine
     *
     * @var array
     */
    protected $settings = [
        'templatesDirectory' => '',
    ];

    public function __construct(array $settings = []) {
        $this->data = array();

        if (!empty($settings['extension'])) {
            $settings['extension'] = '.' . ltrim($settings['extension'], '.');
        } else {
            $settings['extension'] = '';
        }
        $this->settings = array_merge($this->settings, $settings);
    }

    public function get($key) {
        return isset($this->data[$key]) ? $this->data[$key] : null;
    }

    public function set($key, $value) {
        $this->data[$key] = $value;
    }

    public function replace(array $data) {
        foreach ($data as $key => $value) {
            $this->set($key, $value);
        }
    }

    public function all() {
        return (array) $this->data;
    }

    public function clear() {
        $this->data = array();
    }

    public function setTemplatesDirectory($directory) {
        $this->settings['templatesDirectory'] = rtrim($directory, DIRECTORY_SEPARATOR);
    }

    public function getTemplatesDirectory() {
        return $this->settings['templatesDirectory'];
    }

    public function getTemplatePathname($file) {
        return $this->settings['templatesDirectory'] . DIRECTORY_SEPARATOR . ltrim($file, DIRECTORY_SEPARATOR);
    }

    public function display($template, array $data = array()) {
        echo $this->fetch($template, $data);
    }

    public function fetch($template, array $data = array()) {
        $template .= $this->settings['extension'];
        $this->replace($data);

        return $this->render($template);
    }

    /**
     * Render a template file
     *
     * @param  string $template The template pathname, relative to the template base directory
     * @return string           The rendered template string
     * @throws ErrorException   If resolved template pathname is not a valid file
     */
    protected function render($template) {
        $templatePathname = $this->getTemplatePathname($template);
        if (!is_file($templatePathname)) {
            throw new ErrorException("View cannot render `$template`, because the template does not exist.");
        }

        extract($this->all());
        ob_start();
        require $templatePathname;

        return ob_get_clean();
    }

}
